#graph.py
import numpy as np
from point import Point
import sys
import pygame

obstacle_color = (0,0,0) # is black

class Graph(object):
    def __init__(self,shape, unit):
        self.width, self.height = shape
        self.unit = unit
        #rasterization
        self.m, self.n = self.height // self.unit, self.width // self.unit
        self.line_width = 1
        self.mat = np.ones((self.m, self.n))
        self.cost_mat = np.ones((self.m,self.n))*sys.maxsize
        self.obstacle = []

    def constraint(self, p:Point):
        if (p.x >= 0 and p.x < self.n) and (p.y >= 0 and p.y < self.m):
            return True
        else:
            return False
    def set_obstacle(self, obstacle):
        self.obstacle = obstacle
        for p in obstacle:
            self.mat[p.x][p.y] = 0
            #(p.x, p.y) is not reachable

    def get_neighbors(self,p:Point):
        neighbors = []
        #delta = [(1,0),(-1,0),(0,1),(0,-1)]
        delta = [(1,0), (0,1), (-1,0), (0,-1)]
        for d in delta:
            x = p.x + d[0]
            y = p.y + d[1]
            neighbor = Point(x,y)

            if self.constraint(neighbor) and self.mat[neighbor.x][neighbor.y] == 1:
                neighbors.append(neighbor)
        return neighbors

    def draw_path(self, screen, path, color = (200,123,0)):
        #Points is list of tuple[(x1,y1),(x2,y2),...,(xn,yn)]
        if path == False:
            return
        for p in path:
            x = p[0]*self.unit + self.line_width
            y = p[1]*self.unit + self.line_width
            l = self.unit - 2 * self.line_width
            pygame.draw.rect(screen, color, (x,y,l,l),0)


        

    def show_mat(self):
        print(self.mat)
    def show_cost(self):
        print(self.cost_mat)

    def draw(self, screen):
        line_color = (0,0,0)
        for x in range(self.unit, self.height, self.unit):
            pygame.draw.line(screen, line_color, (x,0), (x, self.height), self.line_width)
        for y in range(self.unit, self.width, self.unit):
            pygame.draw.line(screen, line_color, (0,y), (self.width, y), self.line_width)

        #draw obstacle
        if self.obstacle is not None:
            for p in self.obstacle:
                l =  self.unit - 2*self.line_width
                pygame.draw.rect(screen, obstacle_color, (p.x * self.unit, p.y*self.unit, l, l), 0)

